import { RouteRecordRaw } from 'vue-router'
import { constantRoutes, asyncRoutes } from '@/router/index'

export type IAsyncRouteState = {
  addRoutes: RouteRecordRaw[],
  menus: RouteRecordRaw[],
  keepAliveComponents: string[],
  roles: string[]
}

// 判断是否拥有权限
const hasPermission = (route: RouteRecordRaw, roles: string[]): boolean => {
  return route.meta?.roles ? roles.some((role: string) => route.meta?.roles?.includes(role)): false
}

// 过滤出对应角色权限的路由列表
export const filterRoutes = (routes: RouteRecordRaw[], roles: string[]): Array<RouteRecordRaw> => {
  const resRoutes: RouteRecordRaw[] = []
  routes.forEach(route => {
    const _route = { ...route }
    if (hasPermission(_route, roles)) {
      if (_route.children && _route.children.length) {
        _route.children = filterRoutes(_route.children, roles)
      }
      resRoutes.push(_route)
    }
  })
  return resRoutes
}

const state: IAsyncRouteState = {
  addRoutes: [], // 角色权限路由列表
  menus: [],
  keepAliveComponents: [],
  roles: ['super-admin']
}

const mutations = {
  setRoutes: (state: IAsyncRouteState, routers: RouteRecordRaw[]): void => {
    state.addRoutes = routers
    // set dynamic router
    state.menus = constantRoutes.concat(routers)
  },
  setKeepAliveComponents: (state: IAsyncRouteState, componentNames: string[]): void => {
    // set need to cache components
    state.keepAliveComponents = componentNames
  },
  // 删除缓存组件
  removeKeepAliveComponents: (state: IAsyncRouteState, componentName): void => {
    const index = state.keepAliveComponents.find((name: string) => name === componentName)
    if (index) {
      state.keepAliveComponents.splice(Number(index), 1)
    }
  },
  // 清空所有缓存组件
  clearKeepAliveComponents: (state: IAsyncRouteState): void => {
    state.keepAliveComponents = []
  }
}

const actions = {
  // 动态获取菜单
  generateRoutes: ({ commit }): Promise<RouteRecordRaw[]> => {
    return new Promise((resolve) => {
      let accessedRoutes: RouteRecordRaw[] = []
      accessedRoutes = filterRoutes(asyncRoutes, state.roles)
      commit('setRoutes', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

const getters = {
  addRoutes: (state: IAsyncRouteState): RouteRecordRaw[] => state.addRoutes,
  menus: (state: IAsyncRouteState): RouteRecordRaw[] => state.menus,
  keepAliveComponents: (state: IAsyncRouteState): string[] => state.keepAliveComponents,
  roles: (state: IAsyncRouteState): string[] => state.roles
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
